﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace AnimalWars2
{
    public class ComputerPlayer : Player
    {
        public Keys MoveLeftKey;
        public Keys MoveRightKey;
        public Keys ActionKey;
        public AIState m_AIState;
        public float m_DetectionRadius = 60.0f;

        public ComputerPlayer(GameTable gameTableRef, Texture2D texture, Vector2 position, Vector2 velocity, Keys left, Keys right, Keys action, PlayerSide side)
            : base(gameTableRef, texture, position, velocity, side)
        {
            MoveLeftKey = left;
            MoveRightKey = right;
            ActionKey = action;

            m_AIState = AIState.NoAction;
        }

        public override bool MoveLeft()
        {
            //KeyboardState oKS = Keyboard.GetState();
            return m_AIState == AIState.MoveLeft;//oKS.IsKeyDown(MoveLeftKey);
        }

        public override bool MoveRight()
        {
            //KeyboardState oKS = Keyboard.GetState();
            return m_AIState == AIState.MoveRight;//oKS.IsKeyDown(MoveRightKey);
        }

        public override bool Action()
        {
            //KeyboardState oKS = Keyboard.GetState();
            return m_AIState == AIState.Action;//oKS.IsKeyDown(ActionKey);
        }

        public void Play()
        {
            if (m_AIState == AIState.Action)
                m_AIState = AIState.NoAction;
            else
            {
                Ball closestBall = null;
                float closestDist = 1000.0f;

                Ball incomingBall = null;
                float incomingDist = 1000.0f;

                HumanPlayer humanPlayer = null;

                //coleta os dados pra verificar qual a melhor opção de jogada
                foreach (Entity Current in m_GameTable.m_Entities)
                {
                    Ball ball = Current as Ball;

                    if (ball != null && ball.m_Pos.Y < 0.0f) //verifica se é diferente de nulo e se a bola está no lado de cima da quadra
                    {
                        float Dist = Vector2.Distance(m_Pos, ball.m_Pos);

                        //verifica se a bola não está parada
                        if (ball.m_BallState != BallState.Stopped)
                        {
                            //se não estiver parada verifica se ela está vindo direção do computerPlayer
                            if (ball.m_yDirection == -1.0f)
                            {
                                if (Dist < incomingDist)
                                {
                                    incomingDist = Dist;
                                    incomingBall = ball;
                                }
                            }
                        }
                        else
                        {
                            //se estiver parada, verifica se é a menor distancia
                            if (Dist < closestDist)
                            {
                                closestDist = Dist;
                                closestBall = ball;
                            }
                        }
                    }
                    else
                    {
                        //se a bola for nula, é porque é uma entidade de outro tipo
                        //verifica se é o HumanPlayer
                        HumanPlayer player = Current as HumanPlayer;
                        if (player != null)
                        {
                            humanPlayer = player;
                        }
                    }
                }

                //analisa a situação e decide o que fazer

                if (this.m_Ball != null)
                {
                    if (humanPlayer != null)
                    {
                        //se tem referencia pra bola, procura o player pra jogar a bola nele
                        if (Math.Abs(m_Pos.X - humanPlayer.m_Pos.X) <= 5.0f)
                        {
                            base.m_Vel = new Vector2(0.0f, 0.0f);
                            m_AIState = AIState.Action;
                        }
                        else if (m_Pos.X > humanPlayer.m_Pos.X)
                        {
                            m_AIState = AIState.MoveLeft;
                        }
                        else
                        {
                            m_AIState = AIState.MoveRight;
                        }
                    }
                }
                else
                {
                    //verifica se não tem alguma bola vindo na sua direção, usando o raio de detecção
                    if (incomingBall != null && incomingDist < m_DetectionRadius)
                    {
                        //tem bola vindo na direção, verifica em qual lado ela está vindo e aciona a movimentação para o lado contrário
                        if (m_Pos.X > incomingBall.m_Pos.X)
                        {
                            m_AIState = AIState.MoveRight;
                        }
                        else
                        {
                            m_AIState = AIState.MoveLeft;
                        }
                    }
                    else if (closestBall != null)
                    {
                        //se estiver no raio de visão pega a bola na mão
                        if (closestDist < m_VisionRadius)
                        {
                            m_AIState = AIState.Action;
                        }
                        else
                        {
                            //caso contrário, verifica pra qual lado está a bola mais próxima e movimenta o player em direção a ela
                            if (m_Pos.X > closestBall.m_Pos.X)
                            {
                                m_AIState = AIState.MoveLeft;
                            }
                            else
                            {
                                m_AIState = AIState.MoveRight;
                            }
                        }
                    }
                }
            }
        }

        public override void Update(GameTime gameTime)
        {
            this.Play();
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            base.Draw(gameTime, spriteBatch);

            spriteBatch.Draw(m_Texture, new Vector2(329.0f, 18.0f), null, Color.White, 0.0f, new Vector2(0.0f, 0.0f), 1.0f, SpriteEffects.None, 0.5f);
        }
    }
}
